/*****************************************************************************
 * Copyright (c) 2007, Ping Identity
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ping Identity, nor the names of its contributors
 *       may be used to endorse or promote products derived from this software
 *       without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY PING IDENTITY ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 * NO EVENT SHALL PING IDENTITY BE LIABLE FOR ANY DIRECT, INDIRECT, 
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/
#include "infocard.h"
#include "context_test.h"
#include "test_helpers.h"
#include "context.h"
#include "context_internal.h"
#include <openssl/err.h>

static void test_logger(ic_ctx ctx, log_level err_level, const char *reason, void *logger_ctx)
{
	int *logger_int = (int *) logger_ctx;
	(*logger_int)++;
}

static void test_reporter(ic_ctx ctx, const xmlChar *name, const xmlChar *format, const xmlChar *value, void *reporter_ctx)
{
	/* do-nothing */
}
CuSuite* CuGetContextSuite(void)
{
	CuSuite *suite = CuSuiteNew();
	SUITE_ADD_TEST(suite, test_ic_ctx_create_destroy);
	SUITE_ADD_TEST(suite, test_ic_ctx_load_certificate);
	SUITE_ADD_TEST(suite, test_ic_ctx_load_key);
	SUITE_ADD_TEST(suite, test_ic_ctx_set_logger);
	SUITE_ADD_TEST(suite, test_ic_ctx_set_attribute_reporting);
	return suite;
}

void test_ic_ctx_create_destroy(CuTest *tc)
{
	ic_init();
	ic_ctx ctx = ic_ctx_create();
	CuAssertPtrNotNull(tc,ctx);
	CuAssertPtrNotNull(tc, ctx->logger);
	CuAssertPtrNotNull(tc, ctx->attr_reporter);
	CuAssertTrue(tc, ctx->logger_context == NULL);
	CuAssertTrue(tc, ctx->attr_context == NULL);
	ic_ctx_destroy(ctx);
	ic_free();
}
void test_ic_ctx_load_certificate(CuTest *tc)
{
	ic_init();
	ic_ctx ctx = ic_ctx_create();
	ic_ctx_set_logger(ctx, test_logger_printer, NULL);
	CuAssertTrue(tc, ic_ctx_load_certificate(ctx, "tests/test.pem"));
	ic_ctx_destroy(ctx);
	ic_free();
}
void test_ic_ctx_load_key(CuTest *tc)
{
	ic_init();
	ic_ctx ctx = ic_ctx_create();
	ic_ctx_set_logger(ctx, test_logger_printer, NULL);
	CuAssertTrue(tc, ic_ctx_load_certificate(ctx, "tests/test.pem"));
	CuAssertTrue(tc, ic_ctx_load_key(ctx, "tests/test.pem", NULL));
	ic_ctx_destroy(ctx);
	ic_free();
}
void test_ic_ctx_set_logger(CuTest *tc)
{
	int logger_int = 0;
	
	ic_init();
	struct ic_context_t *ctx = ic_ctx_create();
	CuAssertPtrNotNull(tc, ctx->logger);
	ic_ctx_set_logger(ctx, test_logger, &logger_int);
	CuAssertPtrNotNull(tc, ctx->logger);
	CuAssertPtrNotNull(tc, ctx->logger_context);
	/* now a call that will fail */
	ic_ctx_load_certificate(ctx, "non-existant.pem");
	CuAssertTrue(tc, logger_int != 0);	
	
	logger_int = 0;
	ic_ctx_set_logger(ctx, NULL, NULL);
	/* now a call that will fail */
	ic_ctx_load_certificate(ctx, "non-existant.pem");
	CuAssertTrue(tc, logger_int == 0);

	CuAssertPtrNotNull(tc, ctx->logger);
	CuAssertTrue(tc, ctx->logger_context == NULL);
	ic_ctx_destroy(ctx);
	ic_free();
}
void test_ic_ctx_set_attribute_reporting(CuTest *tc)
{	
	/* NOTE: this does not test the reporting mechanism currently, as reporting
	 depends on token parsing logic. */
	
	ic_init();
	struct ic_context_t *ctx = ic_ctx_create();
	CuAssertPtrNotNull(tc, ctx->attr_reporter);

	ic_ctx_set_attribute_reporting(ctx, test_reporter, ctx);
	CuAssertPtrNotNull(tc, ctx->attr_reporter);
	CuAssertPtrNotNull(tc, ctx->attr_context);
	
	ic_ctx_set_attribute_reporting(ctx, NULL, NULL);
	CuAssertPtrNotNull(tc, ctx->attr_reporter);
	CuAssertTrue(tc, ctx->attr_context == NULL);
	
	ic_ctx_destroy(ctx);
	ic_free();
}
